﻿using DotNetty.Buffers;
using DotNetty.Transport.Channels;
using JT809.Protocol;
using JT809.Protocol.Exceptions;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JTT809_2011_Service.JT809
{
    /// <summary>
    /// 下级平台
    /// JT809主链路客户端处理程序
    /// </summary>
    internal class JT809MainClientHandler : SimpleChannelInboundHandler<byte[]>
    {
        private readonly JT809InferiorMsgIdReceiveHandlerBase _handler;

        private readonly JT809AtomicCounterService _jT809AtomicCounterService;

        private readonly ILogger<JT809MainClientHandler> _logger;

        private readonly JT809Serializer _JT809Serializer;

        #region ctor
        public JT809MainClientHandler
            (
            IJT809Config jT809Config,
            ILoggerFactory loggerFactory,
            JT809InferiorMsgIdReceiveHandlerBase handler,
            JT809AtomicCounterServiceFactory jT809AtomicCounterServiceFactorty
            )
        {
            this._handler = handler;
            _JT809Serializer = jT809Config.GetSerializer();
            this._jT809AtomicCounterService = jT809AtomicCounterServiceFactorty.Create(JT809AtomicCounterType.ClientMain.ToString());
            _logger = loggerFactory.CreateLogger<JT809MainClientHandler>();
        }
        #endregion
        protected override void ChannelRead0(IChannelHandlerContext ctx, byte[] msg)
        {
            try
            {
                JT809Package jT809Package = _JT809Serializer.Deserialize(msg);
                _jT809AtomicCounterService.MsgSuccessIncrement();
                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug("accept package success count<<<" + _jT809AtomicCounterService.MsgSuccessCount.ToString());
                }
                Func<JT809Request, JT809Response> handlerFunc;
                if (_handler.HandlerDict.TryGetValue(jT809Package.Header.BusinessType, out handlerFunc))
                {
                    JT809Response jT808Response = handlerFunc(new JT809Request(jT809Package, msg));
                    if (jT808Response != null)
                    {
                        var sendData = _JT809Serializer.Serialize(jT808Response.Package, jT808Response.MinBufferSize);
                        ctx.WriteAndFlushAsync(Unpooled.WrappedBuffer(sendData));
                    }
                }
            }
            catch (JT809Exception ex)
            {
                _jT809AtomicCounterService.MsgFailIncrement();
                if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError("accept package fail count<<<" + _jT809AtomicCounterService.MsgFailCount.ToString());
                    _logger.LogError(ex, "accept msg<<<" + ByteBufferUtil.HexDump(msg));
                }
            }
            catch (Exception ex)
            {
                _jT809AtomicCounterService.MsgFailIncrement();
                if (_logger.IsEnabled(LogLevel.Error))
                {
                    _logger.LogError("accept package fail count<<<" + _jT809AtomicCounterService.MsgFailCount.ToString());
                    _logger.LogError(ex, "accept msg<<<" + ByteBufferUtil.HexDump(msg));
                }
            }
        }
    }
}
